---
title: File layout
description: Guide for Pothos app layouts
---

Pothos tries not to be opinionated about how you structure your code, and provides multiple ways of
doing many things. This short guide covers a few conventions I use, as a starting place for anyone
who is just looking for a decent setup that should just work. Everything suggested here is just a
recommendation and is completely optional.

## Files

Here are a few files I create in almost every Pothos schema I have built:

- `src/server.ts`: Setup and run your server \(This might be graphql-yoga or @apollo/server\)

- `src/builder.ts`: Setup for your schema builder. Does not contain any definitions for types in
  your schema

- `src/schema.ts` or `src/schema/index.ts`: Imports all the files that define part of your schema,
  but does not define types itself. Exports `builder.toSchema()`

- `src/types.ts`: Define shared types used across your schema including a type for your context
  object. This should be imported when creating your builder, and may be used by many other files.

- `src/schema/*.ts`: Actual definitions for your schema types.

## Imports

Import types directly from the files that define them rather than importing from another file like
`index.ts` that re-exports them. `index.ts` files can still be useful for loading all files in a
directory, but they should generally NOT export any values.

## Plugins

Which plugins you use is completely up to you. For my own projects, I will use the `simple-objects`,
`scope-auth`, and `mocks` plugins in every project, and some of the other plugins as needed.

`mocks` and `scope-auth` are fairly self explanatory. The `simple-objects` plugin can make building
out a graph much quicker, because you don't have to have explicit types or models for every object
in your graph. I frequently find that I just want to add an object of a specific shape, and then let
the parent field figure out how to return an object of the right shape.

## Backing models

Pothos gives you a lot of control over how you define the types that your schema and resolvers use,
which can make figuring out the right approach confusing at first. In my projects, I try to avoid
using the `SchemaTypes` approach for defining backing models. Instead, I tend to use model classes
for defining most of the important objects in my graph, and fall back to using either the
simple-objects plugin or `builder.objectRef<Shape>(name).implement({...})` when it does not make
sense to define a class for my data.

## Co-locating queries

In bigger graphs, having all your queries/entry points defined in one place can become hard to
manage. Instead, I prefer to define queries alongside the types they return. For example, queries
for a `User` type would be defined in the same file that contains the definition for the `User`
type, rather than in a central `queries.ts` file \(using `builder.queryField`\).
